
import java.util.ArrayList;

/**
 * Gestiona las operaciones que se van a realizar.
 * @author paco
 */
public class Operaciones
{
	private ArrayList< ArrayList<Simbolo> > operandos;
	private ArrayList< ArrayList<String> > operadores;
	private Integer indice;

	public Operaciones()
	{
		operandos = new ArrayList<ArrayList<Simbolo>>();
		operadores = new ArrayList<ArrayList<String>>();
		indice = -1;
	}
	
	public void appendOperando( Simbolo s )
	{
		operandos.get(indice).add(s);
	}
	
	public void appendOperador( String s )
	{
		operadores.get(indice).add(s);
	}
	
	public void addOperacion()
	{
		ArrayList<Simbolo> op = new ArrayList<Simbolo>();
		ArrayList<String> op2 = new ArrayList<String>();
		operandos.add(op);
		operadores.add(op2);
		indice++;
	}
	
	public String promocion( Simbolo primero, Simbolo anterior, Simbolo actual, Simbolo siguiente)
	{
		StringBuilder builder = new StringBuilder();
		
		if ( primero.getTipo() == actual.getTipo() && anterior == null && siguiente == null )
		{
			builder.append(actual.toString());
		}
		else
		{
			if ( anterior == null )
			{
				if ( primero.getTipo() == Simbolo.ENTERO )
					builder.append("new Integer(");
				else
					builder.append("new Double(");
			}
			
			if ( actual.getTipo() == Simbolo.DOUBLE )
				builder.append(promoDouble(primero, anterior, actual, siguiente));
			else if ( actual.getTipo() == Simbolo.REAL )
				builder.append(promoReal(primero, anterior, actual, siguiente));
			else if ( actual.getTipo() == Simbolo.INT )
				builder.append(promoInt(primero, anterior, actual, siguiente));
			else if ( actual.getTipo() == Simbolo.ENTERO )
				builder.append(promoEntero(primero, anterior, actual, siguiente));
				
			
			if ( siguiente == null )
				builder.append(")");
		}
		
		return builder.toString();
	}
	
	public String promoInt( Simbolo primero, Simbolo anterior, Simbolo actual, Simbolo siguiente)
	{
		StringBuilder builder = new StringBuilder();
		
		if ( primero.getTipo() == Simbolo.ENTERO )
		{
			builder.append(actual.toString());
		}
		else
		{
			if ( anterior == null || anterior.getTipo() != actual.getTipo() )
			{
				builder.append("(new Integer(");
			}
			builder.append(actual.toString());
			if ( siguiente == null || siguiente.getTipo() != actual.getTipo() )
			{
				builder.append("))").append(".toDouble()");
			}
		}
		
		return builder.toString();
	}
	public String promoEntero( Simbolo primero, Simbolo anterior, Simbolo actual, Simbolo siguiente)
	{
		StringBuilder builder = new StringBuilder();
		
		if ( primero.getTipo() == Simbolo.ENTERO )
		{
			builder.append(actual.toString()).append(".intValue()");
		}
		else
		{
			if ( siguiente != null )
			{
				if ( siguiente.getTipo() != Simbolo.ENTERO && siguiente.getTipo() != Simbolo.INT )
				{
					builder.append(actual.toString()).append(".toDouble()");
				}
				else
				{
					builder.append("(new Integer(");
					builder.append(actual.toString()).append(".intValue()");
				}
			}
			else
			{
				builder.append(actual.toString()).append(".toDouble()");
			}
		}
		
		return builder.toString();
	}
	public String promoDouble( Simbolo primero, Simbolo anterior, Simbolo actual, Simbolo siguiente)
	{
		StringBuilder builder = new StringBuilder();
		
		builder.append(actual.toString());
		
		return builder.toString();
	}
	public String promoReal( Simbolo primero, Simbolo anterior, Simbolo actual, Simbolo siguiente)
	{
		StringBuilder builder = new StringBuilder();
		
		builder.append(actual.toString()).append(".doubleValue()");
		
		return builder.toString();
	}
	
	@Override
	public String toString()
	{
		StringBuilder builder = new StringBuilder();
		for ( int i = 0; i < operadores.size();i++)
		{
			ArrayList<Simbolo> op = operandos.get(i);
			ArrayList<String> signos = operadores.get(i);
			Simbolo primero = op.get(0);
			Simbolo anterior = null;
			Simbolo actual = null;
			Simbolo siguiente = null;
			builder.append("  ").append(primero.toString()).append(" ").append(signos.get(0)).append(" ");
			for ( int j = 1; j < op.size(); j++ )
			{
				anterior = actual;
				actual = op.get(j);
				if ( j+1 < op.size() )
				{
					siguiente = op.get(j+1);
				}
				else
				{
					siguiente = null;
				}
				builder.append( promocion(primero, anterior, actual, siguiente) );
				builder.append(signos.get(j));
			}
			builder.append("\n");
		}
		indice = -1;
		operandos.clear();
		operadores.clear();
		
		return builder.toString();
	}
	
	
}
